<?php


namespace app;

use think\facade\Cache;

class Redis
{
    /**
     * redis
     * @var \think\cache\Driver\Redis
     */
    protected static $redis;
    /**
     * Redis constructor.
     */
    protected function __construct()
    {
        if (!extension_loaded('redis')) {
            throw new \BadFunctionCallException('not support: Redis');
        }

        self::$redis = Cache::store('redis');
    }

    /**
     * 获取数据
     * @param $key
     * @return mixed
     */
    public static function get($key)
    {
        $func = function ($key) {
            return $key;
        };
        if (is_array($key)) {
            $key = array_map($func, $key);
            return Cache::store('redis')->mget($key);
        } else {
            //return Cache::store('redis')->get( $key);
            return json_decode(json_encode(Cache::store('redis')->get( $key) ),true);
        }
    }

    /**
     * 写入数据
     * @param string $key
     * @param $value
     * @param int $exprie
     * @return bool
     */
    public static  function set(string $key, $value, int $exprie = 0)
    {
        if ($exprie) {
            $res = Cache::store('redis')->setex( $key, $exprie, $value);
        } else {
            $res = Cache::store('redis')->set( $key, $value);
        }
        return $res;
    }

    /**
     * 删除一个或多个key
     * @param $keys  数组/ 数组以逗号拼接的string
     */
    public static function del($key){
        $isexist=Cache::store('redis')->del($key);
        return 1;
    }

    /**
     * redis 哈希表(hash)类型
     * 返回哈希表 $key 中，所有的域和值。
     * @param $key
     *
     */
    public static function hGetAll($key){
        return Cache::store('redis')->hGetAll($key);
    }

    /**
     * 添加一个VALUE到HASH中。如果VALUE已经存在于HASH中，则返回FALSE。
     * @param string $key
     * @param string $hashKey
     * @param string $value
     */
    public static function hSet( $key, $hashKey, $value ) {
        return Cache::store('redis')->hSet($key, $hashKey, $value);
    }

    /**
     * redis 哈希表(hash)类型
     * 批量填充HASH表。不是字符串类型的VALUE，自动转换成字符串类型。使用标准的值。NULL值将被储存为一个空的字符串。
     * 可以批量添加更新 value,key 不存在将创建，存在则更新值
     * @param  $key
     * @param  $fieldArr  要设置的键对值
     * @return
     * 当key不是哈希表(hash)类型时，返回一个错误。
     */
    public static function hMSet($key,$fieldArr){
        return Cache::store('redis')->hmset($key,$fieldArr);
    }

    /**
     * 取得HASH中的VALUE，如何HASH不存在，或者KEY不存在返回FLASE。
     * @param   string  $key
     * @param   string  $hashKey
     * @return  string  The value, if the command executed successfully BOOL FALSE in case of failure
     */
    public static function hGet($key, $hashKey) {
        return Cache::store('redis')->hGet($key,$hashKey);
    }

    /**
     * 批量取得HASH中的VALUE，如何hashKey不存在，或者KEY不存在返回FLASE。
     * @param string $key
     * @param array $hashKey
     */
    public static function hMGet( $key, $hashKeys ) {
        return Cache::store('redis')->hMGet($key,$hashKeys);
    }

    /**
     * 根据HASH表的KEY，为KEY对应的VALUE自增参数VALUE。浮点型
     * 推荐使用 hIncrByFloat  不推荐使用 hIncrBy(整型)
     * 先用 hIncrByFloat 再使用  hIncrBy  自增无效
     * @param string $key
     * @param string $hashKey
     * @param value  自增值  整型/小数
     */
    public static function hIncrByFloat( $key, $hashKey, $value){
        return Cache::store('redis')->hIncrByFloat( $key, $hashKey, $value);
    }

    /**
     *  删除哈希表key中的一个指定域，不存在的域将被忽略。
     * @param string $key
     * @param string $hashKey
     */
    public static function hDel($key,$hashKey){
        return Cache::store('redis')->hDel( $key, $hashKey);
    }



    /**
     * 添加一个字符串值到LIST容器的顶部（左侧），如果KEY不存在，曾创建一个LIST容器，如果KEY存在并且不是一个LIST容器，那么返回FLASE。
     * @param string $key
     * @param string $val
     */
    public static function lPush($key,$val){
        return	Cache::store('redis')->lPush($key,$val);
    }

    /**
     * 添加一个字符串值到LIST容器的底部（右侧），如果KEY不存在，曾创建一个LIST容器，如果KEY存在并且不是一个LIST容器，那么返回FLASE。
     *
     * @param string $key
     * @param string $val
     */
    public static function rPush($key,$val){
        return	Cache::store('redis')->rPush($key,$val);
    }
    /**
     * 返回LIST顶部（左侧）的VALUE，并且从LIST中把该VALUE弹出。
     * @param string $key
     */
    public static function lPop($key){
        return Cache::store('redis')->lPop($key);
    }
    /**
     * 返回LIST底部（右侧）的VALUE，并且从LIST中把该VALUE弹出。
     * @param string $key
     */
    public static function rPop($key){
        return Cache::store('redis')->rPop($key);
    }

    /**
     * 移除指定数量的value  0移除全部 正整数 从左侧开始移除，负数从右侧移除
     * @param string $key
     */
    public static function lRem($key,$value,$count=0){
        return Cache::store('redis')->lRem($key,$value,$count);
    }

    /**
     * 获取索引范围内的数据
     * @param string $key
     */
    public static function lRange($key,$start,$end){
        return Cache::store('redis')->lRange($key,$start,$end);
    }


    /*
     * 构建一个集合(有序集合)  可排序
     * @param  string $key 集合名称
     * @param  string $value1  值
     * @param  double $score1  值
     * return 被成功添加的新成员的数量，不包括那些被更新的、已经存在的成员。
     */
    public static function zAdd($key,$score1,$value1){
        return Cache::store('redis')->zAdd($key,$score1,$value1);
    }

    /**
     * 返回key对应的有序集合中member的score值。如果member在有序集合中不存在，那么将会返回nil。
     * @param   string  $key
     * @param   string  $member
     * @return  float
     */
    public static function zScore( $key, $member ) {
        return Cache::store('redis')->zScore( $key, $member );
    }

    /**
     * 返回key对应的有序集合中介于min和max间的元素的个数。
     * @param   string  $key
     * @param   string  $start
     * @param   string  $end
     * @return  float
     */
    public static function zCount( $key, $start, $end ) {
        return Cache::store('redis')->zCount( $key, $start, $end );
    }

    /**
     * 返回存储在key对应的有序集合中的元素的个数。
     * @param   string  $key
     * @return  int     the set's cardinality

     */
    public static function zCard($key){
        return Cache::store('redis')->zCard($key);
    }

    /**
     * 将key对应的有序集合中member元素的scroe加上 value     value可以是负值
     * @param   string  $key
     * @param   float   $value (double) value that will be added to the member's score
     * @param   string  $member
     * @return  float   the new value
     * @example
     * <pre>
     * $redis->delete('key');
     * $redis->zIncrBy('key', 2.5, 'member1');  // key or member1 didn't exist, so member1's score is to 0
     *                                          // before the increment and now has the value 2.5
     * $redis->zIncrBy('key', 1, 'member1');    // 3.5
     * </pre>
     * member 成员的新 score 值，以字符串形式表示。
     */
    public static function zIncrBy( $key, $value, $member ) {

        return Cache::store('redis')->zIncrBy( $key, $value, $member );
    }

    /**
     * 取得特定范围内的排序元素,0代表第一个元素,1代表第二个以此类推。-1代表最后一个,-2代表倒数第二个...
     * @param   string  $key
     * @param   int     $start
     * @param   int     $end
     * @param   bool    $withscores
     * @return  array   Array containing the values in specified range.
     * @example
     * <pre>
     * $redis->zAdd('key1', 0, 'val0');
     * $redis->zAdd('key1', 2, 'val2');
     * $redis->zAdd('key1', 10, 'val10');
     * $redis->zRange('key1', 0, -1); // array('val0', 'val2', 'val10')
     * // with scores
     * $redis->zRange('key1', 0, -1, true); // array('val0' => 0, 'val2' => 2, 'val10' => 10)
     * </pre>
     * 指定区间内，带有 score 值(可选)的有序集成员的列表。
     * zRange 根据 score 正序   zRevRange 倒序
     */
    public static function zRange( $key, $start, $end, $withscores = null ) {

        return Cache::store('redis')->zRange( $key, $start, $end, $withscores) ;
    }
    public static function zRevRange( $key, $start, $end, $withscores = null ) {

        return Cache::store('redis')->zRevRange( $key, $start, $end, $withscores) ;
    }

    /**
     * 从有序集合中删除指定的成员。
     * @param   string  $key
     * @param   string  $member1
     * @return  int     Number of deleted values
     */
    public static function zRem( $key, $member1 ) {

        return Cache::store('redis')->zRem( $key, $member1 );
    }

}